package com.bbzn.device.client.service.impl;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.facebody.model.v20191230.*;
import com.aliyuncs.profile.DefaultProfile;
import com.bbzn.device.client.vo.req.FaceEntityVO;
import com.bbzn.device.client.vo.req.FaceVO;
import com.bbzn.device.client.config.FaceProperties;
import com.bbzn.device.client.constant.FaceConstant;
import com.bbzn.device.client.dao.face.FaceDbMapper;
import com.bbzn.device.client.dao.face.FaceMapper;
import com.bbzn.device.client.dataobject.Face;
import com.bbzn.device.client.dataobject.FaceDb;
import com.bbzn.device.client.dataobject.SystemParam;
import com.bbzn.device.client.dto.face.FaceDTO;
import com.bbzn.device.client.exception.DefinitException;
import com.bbzn.device.client.service.FaceService;
import com.bbzn.device.client.service.SystemParamByCacheService;
import com.bbzn.device.client.utils.FaceUtil;
import com.ctg.ag.sdk.biz.AepProductManagementClient;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class FaceServiceImpl implements FaceService {

    @Autowired
    private SystemParamByCacheService systemParamByCacheService;

    @Resource
    private FaceMapper faceMapper;

    @Resource
    private FaceDbMapper faceDbMapper;

    FaceUtil faceUtil = new FaceUtil();

    private static DefaultProfile profile;

    @PostConstruct
    public static DefaultAcsClient getClient() {
        if (profile == null) {
            synchronized (AepProductManagementClient.class) {
                if (profile == null) {
                    profile = DefaultProfile.getProfile("cn-shanghai", FaceProperties.ALIYUN_ACCESS_ID, FaceProperties.ALIYUN_ACCESS_KEY);
                }
            }
        }
        return new DefaultAcsClient(profile);
    }

    @Override
    public int deleteByPrimaryKey(Long id) {
        return faceMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int insert(Face record) {
        return faceMapper.insert(record);
    }

    @Override
    public int insertOrUpdate(Face record) {
        return faceMapper.insertOrUpdate(record);
    }

    @Override
    public int insertOrUpdateSelective(Face record) {
        return faceMapper.insertOrUpdateSelective(record);
    }

    @Override
    public int insertSelective(Face record) {
        return faceMapper.insertSelective(record);
    }

    @Override
    public Face selectByPrimaryKey(Long id) {
        return faceMapper.selectByPrimaryKey(id);
    }

    @Override
    public int updateByPrimaryKeySelective(Face record) {
        return faceMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public int updateByPrimaryKey(Face record) {
        return faceMapper.updateByPrimaryKey(record);
    }

    @Override
    public List<Face> findByAll(Face face) {
        return faceMapper.findByAll(face);
    }

    @Override
    public int updateBatch(List<Face> list) {
        return faceMapper.updateBatch(list);
    }

    @Override
    public int updateBatchSelective(List<Face> list) {
        return faceMapper.updateBatchSelective(list);
    }

    @Override
    public int batchInsert(List<Face> list) {
        return faceMapper.batchInsert(list);
    }

    @Override
    public List<FaceDTO> findAllJoinUser(Face face) {
        return faceMapper.findAllJoinUser(face);
    }

    @Override
    public ListFaceDbsResponse getListFaceDbs(String language) throws Exception {
        IAcsClient client = getClient();
        ListFaceDbsRequest facesDbsRequest = new ListFaceDbsRequest();
        ListFaceDbsResponse faceDbsResponse = new ListFaceDbsResponse();
        try {
            faceDbsResponse = client.getAcsResponse(facesDbsRequest);
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            log.info("查看人脸库列表返回请求》》》 code：" + e.getErrCode() + "msg：" + e.getErrMsg());
            SystemParam systemParam = systemParamByCacheService.getValues(FaceConstant.FACE_ENUM, FaceConstant.FACE_NO_HTTP_RES_ERROR_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), e.getErrMsg());
        }
        return faceDbsResponse;
    }


    @Override
    public void addFaceDb(Long userId, String name, String language) throws Exception {
        IAcsClient client = getClient();
        CreateFaceDbRequest faceDbRequest = new CreateFaceDbRequest();
        faceDbRequest.setName(name);
        try {
            CreateFaceDbResponse faceDbResponse = client.getAcsResponse(faceDbRequest);

            FaceDb faceDb = new FaceDb();
            faceDb.setUserId(userId);
            faceDb.setDbName(name);
            faceDb.setCreateTime(new Date());
            faceDbMapper.insert(faceDb);
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            log.info("创建人脸库返回请求》》》 code：" + e.getErrCode() + "msg：" + e.getErrMsg());
            SystemParam systemParam = systemParamByCacheService.getValues(FaceConstant.FACE_ENUM, FaceConstant.FACE_NO_HTTP_RES_ERROR_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), e.getErrMsg());
        }
    }

    @Override
    public void deleteFaceDb(String name, String language) throws Exception {
        IAcsClient client = getClient();
        DeleteFaceDbRequest faceDbRequest = new DeleteFaceDbRequest();
        faceDbRequest.setName(name);
        try {
            DeleteFaceDbResponse faceDbResponse = client.getAcsResponse(faceDbRequest);
            FaceDb faceDb = new FaceDb();
            faceDb.setDbName(name);
            faceDbMapper.deleteSelective(faceDb);
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            log.info("查询人脸样本列表返回请求》》》 code：" + e.getErrCode() + "msg：" + e.getErrMsg());
            SystemParam systemParam = systemParamByCacheService.getValues(FaceConstant.FACE_ENUM, FaceConstant.FACE_NO_HTTP_RES_ERROR_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), e.getErrMsg());
        }

    }

    @Override
    public ListFaceEntitiesResponse getListFaceEntities(FaceEntityVO reqVO, String language) throws Exception {
        IAcsClient client = getClient();
        ListFaceEntitiesRequest faceEntitiesRequest = new ListFaceEntitiesRequest();
        BeanUtils.copyProperties(faceEntitiesRequest, reqVO);
        ListFaceEntitiesResponse faceEntitiesResponse = new ListFaceEntitiesResponse();
        try {
            faceEntitiesResponse = client.getAcsResponse(faceEntitiesRequest);
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            log.info("查询人脸样本列表返回请求》》》 code：" + e.getErrCode() + "msg：" + e.getErrMsg());
            SystemParam systemParam = systemParamByCacheService.getValues(FaceConstant.FACE_ENUM, FaceConstant.FACE_NO_HTTP_RES_ERROR_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), e.getErrMsg());
        }
        return faceEntitiesResponse;
    }

    @Override
    public GetFaceEntityResponse getFaceEntity(FaceEntityVO reqVO, String language) throws Exception {
        IAcsClient client = getClient();
        GetFaceEntityRequest faceEntityRequest = new GetFaceEntityRequest();
        faceEntityRequest.setDbName(reqVO.getDbName());
        faceEntityRequest.setEntityId(reqVO.getEntityId());
        GetFaceEntityResponse faceEntityResponse = new GetFaceEntityResponse();
        try {
            faceEntityResponse = client.getAcsResponse(faceEntityRequest);
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            log.info("查询人脸样本返回请求》》》 code：" + e.getErrCode() + "msg：" + e.getErrMsg());
            SystemParam systemParam = systemParamByCacheService.getValues(FaceConstant.FACE_ENUM, FaceConstant.FACE_NO_HTTP_RES_ERROR_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), e.getErrMsg());
        }
        return faceEntityResponse;
    }

    @Override
    public void addFaceEntity(FaceEntityVO reqVO, String language) throws Exception {
        IAcsClient client = getClient();
        AddFaceEntityRequest faceEntityRequest = new AddFaceEntityRequest();
        BeanUtils.copyProperties(faceEntityRequest, reqVO);
        try {
            AddFaceEntityResponse faceEntityResponse = client.getAcsResponse(faceEntityRequest);
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            log.info("创建人脸样本返回请求》》》 code：" + e.getErrCode() + "msg：" + e.getErrMsg());
            SystemParam systemParam = systemParamByCacheService.getValues(FaceConstant.FACE_ENUM, FaceConstant.FACE_NO_HTTP_RES_ERROR_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), e.getErrMsg());
        }
    }

    @Override
    public void updateFaceEntity(FaceEntityVO reqVO, String language) throws Exception {
        IAcsClient client = getClient();
        UpdateFaceEntityRequest faceEntityRequest = new UpdateFaceEntityRequest();
        BeanUtils.copyProperties(faceEntityRequest, reqVO);
        try {
            UpdateFaceEntityResponse faceEntityResponse = client.getAcsResponse(faceEntityRequest);
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            log.info("更新人脸样本返回请求》》》 code：" + e.getErrCode() + "msg：" + e.getErrMsg());
            SystemParam systemParam = systemParamByCacheService.getValues(FaceConstant.FACE_ENUM, FaceConstant.FACE_NO_HTTP_RES_ERROR_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), e.getErrMsg());
        }
    }

    @Override
    public void deleteFaceEntity(FaceEntityVO reqVO, String language) throws Exception {
        IAcsClient client = getClient();
        DeleteFaceEntityRequest faceEntityRequest = new DeleteFaceEntityRequest();
        faceEntityRequest.setDbName(reqVO.getDbName());
        faceEntityRequest.setEntityId(reqVO.getEntityId());
        try {
            //1、删除人脸样本时要先删除人脸数据
            //删除阿里云的人脸数据
            GetFaceEntityRequest getEntityRequest = new GetFaceEntityRequest();
            BeanUtils.copyProperties(getEntityRequest, faceEntityRequest);
            GetFaceEntityResponse getEntityResponse = client.getAcsResponse(getEntityRequest);
            if (null != getEntityResponse.getData().getFaces()) {
                getEntityResponse.getData().getFaces().stream().forEach(face -> {
                    DeleteFaceRequest delFaceRequest = new DeleteFaceRequest();
                    delFaceRequest.setDbName(reqVO.getDbName());
                    delFaceRequest.setFaceId(face.getFaceId());
                    try {
                        DeleteFaceResponse faceEntityResponse = client.getAcsResponse(delFaceRequest);
                    } catch (ClientException e) {
                        e.printStackTrace();
                    }
                });
            }
            //删除本地人脸数据
            Face face = new Face();
            face.setDbName(reqVO.getDbName());
            face.setUserId(Long.valueOf(reqVO.getEntityId()));
            faceMapper.deleteSelective(face);

            DeleteFaceEntityResponse faceEntityResponse = client.getAcsResponse(faceEntityRequest);
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            log.info("删除人脸样本返回请求》》》 code：" + e.getErrCode() + "msg：" + e.getErrMsg());
            SystemParam systemParam = systemParamByCacheService.getValues(FaceConstant.FACE_ENUM, FaceConstant.FACE_NO_HTTP_RES_ERROR_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), e.getErrMsg());
        }
    }

    /**
     * face 目前
     * @param file
     * @return
     * @throws Exception
     */
    @Override
    public String uploadFaceImg(MultipartFile file) throws Exception {

        String name= faceUtil.uploadFaceImg(file);
        //加路径名
        String url = FaceProperties.ALIYUN_FACE_URL+name;
        return url;
    }

    @Override
    public List delListImg(List<String> list) throws Exception {
        return faceUtil.deleteObjects(list);
    }

    @Override
    public void addFace(FaceVO reqVO, String userName, String language) throws Exception {
        IAcsClient client = getClient();
        AddFaceRequest faceRequest = new AddFaceRequest();
        BeanUtils.copyProperties(faceRequest, reqVO);
        // 质量分阈值。对新增人脸图片进行质量分析判断，得到的质量分小于该阈值则表示新增人脸图片质量不符合要求，添加失败。取值范围[0.0,100.0]。0.0或空则表示不做质量分判断逻辑。
        faceRequest.setQualityScoreThreshold(8.5F);
        try {
            AddFaceResponse response = client.getAcsResponse(faceRequest);
            Face face = new Face();
            face.setDbName(reqVO.getDbName());
            face.setUserId(Long.valueOf(reqVO.getEntityId()));
            face.setFaceId(response.getData().getFaceId());
            face.setImageUrl(reqVO.getImageUrl());
            face.setCreateTime(new Date());
            face.setCreatedBy(userName);
            faceMapper.insert(face);
            System.out.println(new Gson().toJson(response));
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            log.info("添加人脸数据返回请求》》》 code：" + e.getErrCode() + "msg：" + e.getErrMsg());
            SystemParam systemParam = systemParamByCacheService.getValues(FaceConstant.FACE_ENUM, FaceConstant.FACE_NO_HTTP_RES_ERROR_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), e.getErrMsg());
        }
    }

    @Override
    public void batchAddFaces(FaceVO reqVO, String language) throws Exception {
        IAcsClient client = getClient();
        BatchAddFacesRequest facesRequest = new BatchAddFacesRequest();
        facesRequest.setDbName(reqVO.getDbName());
        facesRequest.setEntityId(reqVO.getEntityId());
        // 人脸信息。
        List<BatchAddFacesRequest.Faces> facesList = new ArrayList<>();
        BatchAddFacesRequest.Faces faces = new BatchAddFacesRequest.Faces();
        faces.setExtraData(reqVO.getExtraData());
        faces.setImageURL(reqVO.getImageUrl());
        facesList.add(faces);
        facesRequest.setFaces(facesList);
        facesRequest.setQualityScoreThreshold(reqVO.getQualityScoreThreshold());
        try {
            BatchAddFacesResponse response = client.getAcsResponse(facesRequest);
            System.out.println(new Gson().toJson(response));
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            log.info("批量添加人脸数据返回请求》》》 code：" + e.getErrCode() + "msg：" + e.getErrMsg());
            SystemParam systemParam = systemParamByCacheService.getValues(FaceConstant.FACE_ENUM, FaceConstant.FACE_NO_HTTP_RES_ERROR_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), e.getErrMsg());
        }
    }

    @Override
    public SearchFaceResponse searchFace(FaceVO reqVO, String language) throws Exception {
        IAcsClient client = getClient();
        SearchFaceRequest faceRequest = new SearchFaceRequest();
        BeanUtils.copyProperties(faceRequest, reqVO);
        SearchFaceResponse faceResponse = new SearchFaceResponse();
        try {
            faceResponse = client.getAcsResponse(faceRequest);
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            log.info("搜索人脸数据返回请求》》》 code：" + e.getErrCode() + "msg：" + e.getErrMsg());
            SystemParam systemParam = systemParamByCacheService.getValues(FaceConstant.FACE_ENUM, FaceConstant.FACE_NO_HTTP_RES_ERROR_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), e.getErrMsg());
        }
        return faceResponse;
    }

    @Override
    public void deleteFace(FaceVO reqVO, String language) throws Exception {
        IAcsClient client = getClient();
        DeleteFaceRequest faceRequest = new DeleteFaceRequest();
        faceRequest.setDbName(reqVO.getDbName());
        faceRequest.setFaceId(reqVO.getFaceId());
        try {
            DeleteFaceResponse faceEntityResponse = client.getAcsResponse(faceRequest);
            //删除本地人脸数据
            Face face = new Face();
            face.setDbName(reqVO.getDbName());
            face.setFaceId(reqVO.getFaceId());
            Face fa = faceMapper.selectSelective(face);
            if (null == fa || null == fa.getImageUrl()) {
                return;
            }
            List<String> list = new ArrayList<>();
            list.add(fa.getImageUrl().substring(47));
            delListImg(list);
            faceMapper.deleteSelective(face);
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            log.info("删除人脸样本返回请求》》》 code：" + e.getErrCode() + "msg：" + e.getErrMsg());
            SystemParam systemParam = systemParamByCacheService.getValues(FaceConstant.FACE_ENUM, FaceConstant.FACE_NO_HTTP_RES_ERROR_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), e.getErrMsg());
        }
    }
}



